package com.sunda.spmswms.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sunda.spmscommon.ResponseResult;
import com.sunda.spmscommon.feign.IFeignServiceCommon;
import com.sunda.spmscommon.service.ISysLogService;
import com.sunda.spmscommon.utils.DataToPage;
import com.sunda.spmswms.entity.*;
import com.sunda.spmswms.mapper.*;
import com.sunda.spmswms.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.sunda.spmscommon.Constans.*;

/**
 * <p>
 * SAP交货单表头 服务实现类
 * </p>
 *
 * @author Wayne
 * @since 2021-03-22
 */
@Slf4j
@Service
public class SapDeliveryNoteServiceImpl extends ServiceImpl<SapDeliveryNoteMapper, SapDeliveryNote> implements ISapDeliveryNoteService {

    @Autowired
    SapDeliveryNoteMapper sapDeliveryNoteMapper;

    @Autowired
    SapDeliveryNoteDtlMapper sapDeliveryNoteDtlMapper;
    @Autowired
    IWhsStorageService iWhsStorageService;
    @Autowired
    SapPackageNoteMapper sapPackageNoteMapper;
    @Autowired
    SapBoxNoteMapper sapBoxNoteMapper;
    @Autowired
    SapBoxNoteDtlMapper sapBoxNoteDtlMapper;
    @Autowired
    WhsStorageInventoryMapper whsStorageInventoryMapper;
    @Autowired
    ISapBoxNoteDtlService iSapBoxNoteDtlService;
    @Autowired
    IWhsInventoryInfoService iWhsInventoryInfoService;
    @Autowired
    IShelfOnTaskService iShelfOnTaskService;
    @Autowired
    IWhsOperateLogService iWhsOperateLogService;
    @Autowired
    ISapDeliveryNoteLogService iSapDeliveryNoteLogService;
    @Autowired
    IShelfOnTaskDtlService iShelfOnTaskDtlService;

    @Autowired
    IFeignServiceCommon iFeignServiceCommon;

    @Autowired
    ISysLogService iSysLogService;

    /**
     * {
     * "documentDate": "2021-04-16",
     * "pdaSn": "WebClient",
     * "sapBoxNote": [
     * {
     * "boxNote": "ZX-10215800021-0202",
     * "boxQtyReceived": 1,
     * "storageUuid": "b95946ac1dab42b79ade3438acb0b53a",
     * "remarks":"Your remarks"
     * }
     * ],
     * "sapDeliveryNote": {
     * "deliveryNoteSap": "1180066380",
     * "mobileType": "101",
     * "spmsStatus": "6"
     * }
     * }
     */
    @Override
    public ResponseResult sapDeliveryNoteRecX(JSONObject doc, String userId) {
        String pdaSn = doc.containsKey("pdaSn") ? doc.getString("pdaSn") : "WebClient";
        JSONObject sapDeliveryNote = doc.getJSONObject("sapDeliveryNote");
        JSONArray sapBoxNote = doc.getJSONArray("sapBoxNote");

        if (null == sapDeliveryNote || null == sapBoxNote) {
            return ResponseResult.error("sapDeliveryNote and sapBoxNote is mandatory required");
        }

        try {
            // 1. 调用备件来货确认验收接口,验证收货
            ResponseResult checkSapDeliveryNoteResult = checkSapDeliveryNote(userId, doc);
            if (null == checkSapDeliveryNoteResult || checkSapDeliveryNoteResult.getCode() != 200) {
                return ResponseResult.error("确认验收失败");
            }
            // 验证收货成功
            // 2. 完成上架任务表头更新
            String deliveryNoteSap = sapDeliveryNote.getString("deliveryNoteSap");
            ShelfOnTask shelfOnTask = iShelfOnTaskService.completeShelfOnTask(userId, deliveryNoteSap, pdaSn, "1","1","3");
            if (null == shelfOnTask) {
                // 上架任务表头更新失败
                return ResponseResult.error("Error when update Shelf On tasks");
            }

            //3. 更新上架任务详情
            String shelfOnUuid = shelfOnTask.getUuid();
            JSONArray shelfOnTaskDtl = new JSONArray();
            for (int i = 0; i < sapBoxNote.size(); i++) {
                JSONObject oObj = sapBoxNote.getJSONObject(i);
                JSONObject jobj = new JSONObject();
                jobj.put("boxNote", oObj.getString("boxNote"));
                jobj.put("storageUuid", oObj.getString("storageUuid"));
                jobj.put("boxQtyReceived", StringUtils.isNotEmpty(oObj.getString("boxQtyReceived"))?oObj.getDouble("boxQtyReceived"):0);
                jobj.put("deliveryNoteSap", deliveryNoteSap);
                shelfOnTaskDtl.add(jobj);
            }

            if (null == shelfOnUuid || null == shelfOnTaskDtl) {
                return ResponseResult.error("shelfOnUuid and shelfOnTaskDtl is mandatory required");
            }

           return iShelfOnTaskDtlService.completeShelfOnTaskDtlByBoxNote(shelfOnUuid, shelfOnTaskDtl, userId);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error("更新交货单信息失败");
        }
    }

    /**
     * 贸易货一步收化接口
     * {
     * "SapDeliveryNote": {
     * "deliveryNoteSap": "1180066308",
     * "spmsStatus": "6",
     * "documentDate": "20210417",
     * "postingDate": "20210417",
     * "mobileType": "101",
     * "remarks": "remarks for this sapn DN"
     * },
     * "SapDeliveryNoteDtl": [
     * {
     * "deliveryNoteSap": "1180066308",
     * "deliveryNoteSapItem": 10,
     * "materialNo": "130010159",
     * "deliveryQty": 200,
     * "receivedQty": 200,
     * "actualQtySales": 200,
     * "storageUuidList": [
     * {
     * "storageUuid": "64eaf8633b3e4b8aa276970f2e31785b",
     * "qty": 100
     * },
     * {
     * "storageUuid": "64eaf8633b3e4b8aa276970f2e31785c",
     * "qty": 100
     * }
     * ]
     * }
     * ]
     * }
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult sapDeliveryNoteRecM(JSONObject jsonObject, String userId) {
        JSONObject SapDeliveryNote = jsonObject.getJSONObject("SapDeliveryNote");
        JSONArray SapDeliveryNoteDtl = jsonObject.getJSONArray("SapDeliveryNoteDtl");
        if (null == SapDeliveryNote || null == SapDeliveryNoteDtl || SapDeliveryNoteDtl.size() == 0) {
            return ResponseResult.error("SapDeliveryNote and SapDeliveryNoteDtl are mandatory required");
        }

        try {
            /**
             * 完成表头更新
             *   1. deliveryNoteSap, SAP DN单号，必须
             *   2. spmsStatus, 表单当前状态，必须
             *   3. remarks, 收货单备注，可选
             *   4. documentDate, 凭证日期-开始处理日期,可选
             *   5. postingDate, 过账日期-提交SAP日期,可选
             *   6. mobileType, 移动类型,可选
             * */
            String deliveryNoteSap = SapDeliveryNote.getString("deliveryNoteSap");
            String spmsStatus = SapDeliveryNote.getString("spmsStatus");
            String remarks = SapDeliveryNote.getString("remarks");
            String operateUser = SapDeliveryNote.getString("operateUser");
            String documentDate = SapDeliveryNote.getString("documentDate");
            String postingDate = SapDeliveryNote.getString("postingDate");
            String mobileType = SapDeliveryNote.getString("mobileType");

            ResponseResult sapDNUpdateResult = updateSapDeliveryNote(deliveryNoteSap, spmsStatus, remarks, documentDate, postingDate, mobileType, userId, operateUser);

            if (sapDNUpdateResult.getCode() != 200) {
                // 表头更新失败，返回
                throw new Exception("sapDeliveryNoteRecM 贸易货一步收货接口 表头状态更新错误");
            }

            /**
             * 更新交货单行项目、库存信息(贸易货)
             * */

            ResponseResult sapDNDtlUpdateResult = updateSapDeliveryNoteDtl(jsonObject, userId);

            if (sapDNDtlUpdateResult.getCode() != 200) {
                // 更新交货单行项目失败，返回
                throw new Exception("sapDeliveryNoteRecM 贸易货一步收货接口 行项目更新错误");
            }

            return sapDNDtlUpdateResult;

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("======= insertSapDeliveryNote " + e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseResult.error();
        }
    }

    // 据据DN单号获取全部的入库单数据
    @Override
    public Map<String, Object> getOrderReceiveDatabySapDN(String deliveryNoteSap) {
        if (StringUtils.isEmpty(deliveryNoteSap)) {
            return null;
        }
        SapDeliveryNote sapDN = sapDeliveryNoteMapper.selectOne(new QueryWrapper<SapDeliveryNote>().eq("DELIVERY_NOTE_SAP", deliveryNoteSap));
        if (sapDN == null) {
            return null;
        }
        String packageNote = sapDN.getPackageNote();
        Map deliveryData = new HashMap();
        deliveryData.put("sapDN", sapDN);

        if (null == packageNote || "".equals(packageNote)) {
            // 贸易货， 从SAP_DELIVERY_NOTE_DTL获取行数据
            //List<SapDeliveryNoteDtl> sapDeliveryNoteDtls = sapDeliveryNoteDtlMapper.selectList(new QueryWrapper<SapDeliveryNoteDtl>().eq("DELIVERY_NOTE_SAP", deliveryNoteSap));
            List<Map<String, Object>> sapDeliveryNoteDtls = this.baseMapper.sapDeliveryNoteDtls(deliveryNoteSap);
            deliveryData.put("sapDeliveryNoteDtls", sapDeliveryNoteDtls);
        } else {
            // 备件货， 从SAP_BOX_NOTE获取行数据
            List<SapBoxNote> sapBoxNotes = sapBoxNoteMapper.selectList(new QueryWrapper<SapBoxNote>().eq("PACKAGE_NOTE", packageNote));
            deliveryData.put("sapBoxNotes", sapBoxNotes);
        }
        return deliveryData;
    }

    // 根据条件查询sapDN单
    @Override
    public Map<String, Object> getSapDeliveryNote(String userId, JSONObject searchCriteria) {
        String werks = StringUtils.isNotEmpty(searchCriteria.getString("werks")) ? searchCriteria.getString("werks"):null;
        String whsLocationCode = StringUtils.isNotEmpty(searchCriteria.getString("whsLocationCode")) ? searchCriteria.getString("whsLocationCode") : null;
        String deliveryNoteSap = StringUtils.isNotEmpty(searchCriteria.getString("deliveryNoteSap")) ? searchCriteria.getString("deliveryNoteSap"):null;
        String deliveryType = StringUtils.isNotEmpty(searchCriteria.getString("deliveryType")) ? searchCriteria.getString("deliveryType") : null;
        String deliveryNoteSrm = StringUtils.isNotEmpty(searchCriteria.getString("deliveryNoteSrm")) ? searchCriteria.getString("deliveryNoteSrm") : null;
        String spmsMark = StringUtils.isNotEmpty(searchCriteria.getString("spmsMark")) ? searchCriteria.getString("spmsMark") : null;
        String spmsStatus = StringUtils.isNotEmpty(searchCriteria.getString("spmsStatus")) ? searchCriteria.getString("spmsStatus") : null;
        String supplierCode = StringUtils.isNotEmpty(searchCriteria.getString("supplierCode")) ? searchCriteria.getString("supplierCode") : null;
        String plaStartDate = StringUtils.isNotEmpty(searchCriteria.getString("plaStartDate")) ? searchCriteria.getString("plaStartDate") : null;
        String plaEndDate = StringUtils.isNotEmpty(searchCriteria.getString("plaEndDate")) ? searchCriteria.getString("plaEndDate") : null;
        String sapVoucherNumber=StringUtils.isNotEmpty(searchCriteria.getString("sapVoucherNumber")) ? searchCriteria.getString("sapVoucherNumber") : null;
        int pageNo = StringUtils.isNotEmpty(searchCriteria.getString("pageNo")) ? searchCriteria.getIntValue("pageNo") : 1;
        int pageSize = StringUtils.isNotEmpty(searchCriteria.getString("pageSize")) ? searchCriteria.getIntValue("pageSize") : 20;

        // 如果指定了deliveryNoteSap，首先查询此deliveryNoteSap是否存在，若不存在，调用sap接口刷新数据
        if(StringUtils.isNotEmpty(deliveryNoteSap)){
            SapDeliveryNote sapDeliveryNote=this.baseMapper.selectOne(new QueryWrapper<SapDeliveryNote>().eq("DELIVERY_NOTE_SAP",deliveryNoteSap));
            if(null==sapDeliveryNote){
                ResponseResult sapReturnedData = getNonExistSapDeliveryNote(deliveryNoteSap,"", userId);
                if (sapReturnedData.getCode() != 200){
                    Map<String, Object> map = new HashMap<>();
                    map.put("sapReturnedData", sapReturnedData.getData().get("sapReturnedData").toString());
                    map.put("dataToSap", sapReturnedData.getData().get("dataToSap").toString());
                    return map;
                }
            }
        }

        List<Map<String, Object>> sapDN = new ArrayList<>();
        PageHelper.startPage(pageNo, pageSize);
        if ("M".equals(spmsMark)) {
            sapDN = sapDeliveryNoteMapper.getSapDeliverNoteM(userId, deliveryNoteSap, deliveryType, deliveryNoteSrm, spmsMark, supplierCode, plaStartDate, plaEndDate, spmsStatus,sapVoucherNumber,werks,whsLocationCode);
        } else {
            sapDN = sapDeliveryNoteMapper.getSapDeliverNote(userId, deliveryNoteSap, deliveryType, deliveryNoteSrm, spmsMark, supplierCode, plaStartDate, plaEndDate, spmsStatus,sapVoucherNumber,werks,whsLocationCode);
        }
        PageInfo<Map<String, Object>> pageData = new PageInfo<>(sapDN);
        Map<String, Object> pageInfo = new HashMap<>();
        pageInfo.put("records", pageData.getList());
        pageInfo.put("total", pageData.getTotal());
        pageInfo.put("size", pageData.getSize());
        pageInfo.put("current", pageData.getPageNum());
        pageInfo.put("pages", pageData.getPages());
        return pageInfo;
    }

    public ResponseResult getNonExistSapDeliveryNote(String deliveryNoteSap,String status, String userId) {
        String json = "{\n" +
                "    \"REQUEST\": {\n" +
                "        \"ESB_ATTRS\": {\n" +
                "            \"App_ID\": \"SPMS\", \n" +
                "            \"Application_ID\": \"00020000000002\", \n" +
                "            \"Transaction_ID\": " + "\"" + UUID.randomUUID() + "\"" +
                "        }, \n" +
                "        \"REQUEST_DATA\": {\n" +
                "            \"Head\": {\n" +
                "                \"iVbeln\": " + "\"" + deliveryNoteSap + "\",\n" +
                "                \"iStatus\": " + "\"" + status + "\"\n" +
                "            }, \n" +
                "            \"Operation\": \"Z_SPMS_GETDN_REST\", \n" +
                "            \"Type\": \"GETDN\"\n" +
                "        }\n" +
                "    }\n" +
                "}";
        try {
            String message = iFeignServiceCommon.sendRestToSapCommon(JSONObject.parseObject(json));
            if (StringUtils.isEmpty(message)) {
                return ResponseResult.error();
            }
            JSONObject doc = JSONObject.parseObject(message).getJSONObject("RESPONSE").getJSONObject("RETURN_DATA");
            if (doc.containsKey("O_TYPE") && "S".equals(doc.getString("O_TYPE"))){
                /** 更新交货单表头、供应商、行项目等信息 */
                insertSapDeliveryNote(doc);
                iSapDeliveryNoteLogService.insertSapRequestRecord(deliveryNoteSap, userId, UPDATE_DELIVERY_NOTE, JSONObject.parseObject(message).toJSONString(), JSONObject.parseObject(json).toJSONString());
                return ResponseResult.success();
            }else {
                iSapDeliveryNoteLogService.insertSapRequestRecord(deliveryNoteSap, userId, UPDATE_DELIVERY_NOTE_ERROR, JSONObject.parseObject(message).toJSONString(), JSONObject.parseObject(json).toJSONString());
                return ResponseResult.error().add("dataToSap", JSONObject.parseObject(json)).add("sapReturnedData", JSONObject.parseObject(message));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error();
        }
    }

    // 更新sapDN
    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized ResponseResult updateSapDeliveryNote(String deliveryNoteSap, String spmsStatus, String remarks, String documentDate, String postingDate, String mobileType, String userId, String operateUser) {
        /** 贸易货确认收货之前判断：送货单表字段包装单号为空，则判断如果物料本身是备件，就不让操作； */
        ResponseResult checkResult = checkDataFormat(deliveryNoteSap, spmsStatus);
        if (checkResult.getCode() != 200){
            return checkResult;
        }
        try {
            SapDeliveryNote sapDeliveryNote = new SapDeliveryNote();
            sapDeliveryNote.setSpmsStatus(spmsStatus);
            sapDeliveryNote.setRemarks(remarks);
            sapDeliveryNote.setDocumentDate(documentDate);
            sapDeliveryNote.setPostingDate(postingDate);
            sapDeliveryNote.setMobileType(mobileType);
            sapDeliveryNote.setUserId(userId);
            if (StringUtils.isNotEmpty(operateUser)){
                sapDeliveryNote.setOperateUser(operateUser);
            }

            QueryWrapper<SapDeliveryNote> queryWrapper = new QueryWrapper<SapDeliveryNote>()
                    .eq("DELIVERY_NOTE_SAP", deliveryNoteSap);
            int resp = this.baseMapper.update(sapDeliveryNote, queryWrapper);
            if (resp > 0) {
                addSapDeliveryNoteLog(spmsStatus, deliveryNoteSap, userId);
                return ResponseResult.success();
            }
            return ResponseResult.error();
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseResult.error();
        }
    }

    /** 贸易货确认收货之前判断：送货单表字段包装单号为空，则判断如果物料本身是备件，就不让操作； */
    ResponseResult checkDataFormat(String deliveryNoteSap, String spmsStatus){
        if (StringUtils.isEmpty(deliveryNoteSap) || StringUtils.isEmpty(spmsStatus)){
            return ResponseResult.error("请求参数错误请重试");
        }
        SapDeliveryNote sapDeliveryNote = this.baseMapper.selectOne(new QueryWrapper<SapDeliveryNote>().eq("DELIVERY_NOTE_SAP", deliveryNoteSap));
        if (sapDeliveryNote == null){
            return ResponseResult.error("交货单信息不存在");
        }
        /** 包装单号为空则交货单为贸易货，获取贸易货的行数据，及物料本身信息数据判断是否能收货 */
        if (StringUtils.isEmpty(sapDeliveryNote.getPackageNote()) && StringUtils.isEmpty(sapDeliveryNote.getSpmsStatus())){
            List<Map<String, Object>> mapList = this.baseMapper.getDeliveryNoteInfo(deliveryNoteSap);
            for (Map<String, Object> map : mapList){
                if (map.get("spmsMark") != null && "X".equals(map.get("spmsMark").toString())){
                    return ResponseResult.error().add("error", "贸易货交货单" + deliveryNoteSap + "中存在备件物料" + map.get("materialNo").toString() + "，请检查数据是否正确");
                }
            }
        }
        return ResponseResult.success();
    }


    /**
     * SAP交货单表头状态更新日志记录: 2-下发到PDA; 3-收货中; 6-已验收待上传SAP; 7-提交SAP失败; 8-提交SAP完成; 11-关闭; 7，8 不会在此处调用。
     */
    void addSapDeliveryNoteLog(String spmsStatus, String deliveryNoteSap, String userId) {
        if ("1".equals(spmsStatus)) {
            iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(deliveryNoteSap, userId, UPDATE_SAP_DELIVERY_NOTE1);
        }
        if ("2".equals(spmsStatus)) {
            iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(deliveryNoteSap, userId, UPDATE_SAP_DELIVERY_NOTE2);
        }
        if ("3".equals(spmsStatus)) {
            iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(deliveryNoteSap, userId, UPDATE_SAP_DELIVERY_NOTE3);
        }
        if ("6".equals(spmsStatus)) {
            iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(deliveryNoteSap, userId, UPDATE_SAP_DELIVERY_NOTE6);
        }
        if ("11".equals(spmsStatus)) {
            iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(deliveryNoteSap, userId, UPDATE_SAP_DELIVERY_NOTE11);
        }
    }

    /**
     * 贸易货交货单更新接口————更新交货单行项目信息，以及贸易货库存信息
     * {
     * "SapDeliveryNoteDtl": [{
     * "deliveryNoteSap": "1180066360",
     * "deliveryNoteSapItem": 10,
     * "materialNo": "130010159",
     * "deliveryQty": 2,
     * "receivedQty": 2,
     * "actualQtySales":2,
     * "itemStatus":"1",
     * "storageUuidList": [{
     * "storageUuid": "64eaf8633b3e4b8aa276970f2e31785b",
     * "qty": 1
     * }]
     * }]
     * }
     *
     * @param doc
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult updateSapDeliveryNoteDtl(JSONObject doc, String userId) {
        if (!doc.containsKey("SapDeliveryNoteDtl") || doc.getJSONArray("SapDeliveryNoteDtl").size() == 0) {
            return ResponseResult.error("请求参数错误");
        }
        try {
            JSONArray array = doc.getJSONArray("SapDeliveryNoteDtl");
            for (int i = 0; i < array.size(); i++) {
                JSONObject obj = array.getJSONObject(i);
                SapDeliveryNoteDtl sapDeliveryNoteDtl = new SapDeliveryNoteDtl();
                QueryWrapper<SapDeliveryNoteDtl> queryWrapper = new QueryWrapper<SapDeliveryNoteDtl>()
                        .eq("DELIVERY_NOTE_SAP", obj.getString("deliveryNoteSap"))
                        .eq("DELIVERY_NOTE_SAP_ITEM", obj.getString("deliveryNoteSapItem"));
                sapDeliveryNoteDtl.setReceivedQty(StringUtils.isEmpty(obj.getString("receivedQty")) ? 0 : Double.parseDouble(obj.getString("receivedQty")));
                sapDeliveryNoteDtl.setActualQtySales(StringUtils.isEmpty(obj.getString("actualQtySales")) ? 0 : obj.getDoubleValue("actualQtySales"));
                sapDeliveryNoteDtl.setItemStatus(obj.getString("itemStatus"));
                sapDeliveryNoteDtl.setRemarks(obj.getString("remarks"));

                String strStorageUuidList = obj.getJSONArray("storageUuidList").toJSONString();
                sapDeliveryNoteDtl.setTempStorage(strStorageUuidList);

                /** 贸易货————根据交货单号和行号，更新交货单行项目指定行实收数量字段；交货单行项目实收数量更新成功才能执行  库存更新  操作； */
                int resp = sapDeliveryNoteDtlMapper.update(sapDeliveryNoteDtl, queryWrapper);

                if (resp > 0) {
                    /** 更新贸易货库存信息 */
                    String materialNo = obj.getString("materialNo");
                    JSONArray storageUuidList = obj.getJSONArray("storageUuidList");
                    /** 一个物料存入多个储位，需要每个储位单独查询是否已有该物料库存然后写入 */
                    if (storageUuidList.size() > 0) {
                        for (int item = 0; item < storageUuidList.size(); item++) {
                            String storageUuid = storageUuidList.getJSONObject(item).getString("storageUuid");
                            double qty = Double.parseDouble(storageUuidList.getJSONObject(item).getString("qty"));
                            if (qty != 0) {
                                /** 如果该物料在该储位已经存在，则更新对应储位下物料的库存数量；如果不存在，则新建一条 储位-物料-数量 的数据； */
                                QueryWrapper<WhsStorageInventory> wrapper = new QueryWrapper<WhsStorageInventory>().eq("UUID", storageUuid).eq("MATERIAL_NO", materialNo);
                                WhsStorageInventory storageInventory = whsStorageInventoryMapper.selectOne(wrapper);
                                WhsStorageInventory whsStorageInventory = new WhsStorageInventory();
                                if (storageInventory != null) {
                                    whsStorageInventory.setQuantity(storageInventory.getQuantity() + qty);
                                    whsStorageInventory.setAvailableQty(storageInventory.getAvailableQty() + qty);
                                    /** 物料在对应储位已存在数据，则更新库存数量和可用数量； */
                                    whsStorageInventoryMapper.update(whsStorageInventory, wrapper);
                                } else {
                                    whsStorageInventory.setUuid(storageUuid);
                                    whsStorageInventory.setMaterialNo(materialNo);
                                    whsStorageInventory.setQuantity(qty);
                                    whsStorageInventory.setAvailableQty(qty);
                                    /** 物料在对应储位不存在数据，则新建一条 储位-物料-数量 的数据； */
                                    whsStorageInventoryMapper.insert(whsStorageInventory);
                                }
                                WhsStorage whsStorage = iWhsStorageService.getWhsStorageByUuid(storageUuid);
                                /** 记录自管仓 贸易货 按物料 上架 增加储位库存日志 */
                                iWhsOperateLogService.insertWhsOperateLogMS(storageUuid, materialNo, qty, obj.getString("deliveryNoteSap"), TRADE_GOODS_INTO_STORAGE, userId,
                                        whsStorage.getWerks(), whsStorage.getWhsLocationCode());
                            }
                        }
                    }
                } else {
                    return ResponseResult.error("更新行项目数据失败");
                }
            }
            /** 添加 更新储位库存 的日志记录，交货单号取行项目里第一行交货单号即可 */
            iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(array.getJSONObject(0).getString("deliveryNoteSap"), userId, UPDATE_STORAGE_INVENTORY);
            /** 添加 更新交货单详情 的日志记录，交货单号取行项目里第一行交货单号即可 */
            iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(array.getJSONObject(0).getString("deliveryNoteSap"), userId, UPDATE_SAP_DELIVERY_NOTE_DTL);
            return ResponseResult.success();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("======= insertSapDeliveryNote " + e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseResult.error();
        }
    }

    /***
     * {
     * 	"sapBoxNotes": [{
     * 		"boxNote": "ZX-10218300001-0202",
     * 		"boxQtyReceived": 1,
     * 		"storageUuid": "b95946ac1dab42b79ade3438acb0b53h",
     * 		"qty": 1,
     * 		"itemStatus": "1"
     *        }]
     * }
     * 备件货收货更新箱码信息
     * @param doc
     * @return
     */
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public ResponseResult updateSapBoxNote(JSONObject doc) {
//        if (!doc.containsKey("sapBoxNotes") || doc.getJSONArray("sapBoxNotes").size() == 0){
//            return ResponseResult.error("请求参数错误");
//        }
//        try {
//            JSONArray sapBoxNotes = doc.getJSONArray("sapBoxNotes");
//            for (int i = 0; i < sapBoxNotes.size(); i++){
//                JSONObject object = sapBoxNotes.getJSONObject(i);
//                SapBoxNote sapBoxNote = new SapBoxNote();
//                sapBoxNote.setBoxQtyReceived(StringUtils.isEmpty(object.getString("boxQtyReceived")) ? null : Integer.parseInt(object.getString("boxQtyReceived")));
//                sapBoxNote.setItemStatus(StringUtils.isEmpty(object.getString("itemStatus")) ? null : object.getString("itemStatus"));
//                /** 更新箱码实收数量、状态 */
//                int resp = sapBoxNoteMapper.update(sapBoxNote, new QueryWrapper<SapBoxNote>().eq("BOX_NOTE", object.getString("boxNote")));
//                /** 更新箱码库存。备件货按箱码存储，储位 uuid + 箱码可做唯一性 */
//                if (StringUtils.isNotEmpty(object.getString("qty")) && StringUtils.isNotEmpty(object.getString("storageUuid"))){
//                    QueryWrapper<WhsStorageInventory> queryWrapper = new QueryWrapper<WhsStorageInventory>()
//                            .eq("UUID", object.getString("storageUuid")).eq("BOX_NOTE", object.getString("boxNote"));
//                    WhsStorageInventory whsStorageInventory = new WhsStorageInventory();
//                    whsStorageInventory.setUuid(object.getString("storageUuid"));
//                    whsStorageInventory.setBoxNote(object.getString("boxNote"));
//                    whsStorageInventory.setQuantity(Double.parseDouble(object.getString("qty")));
//                    if (whsStorageInventoryMapper.selectOne(queryWrapper) == null){
//                        /** 备件货按箱码存储，每个箱子的箱码数量都是 1，可用库存字段忽略直接使用库存数量字段——QUANTITY */
//                        whsStorageInventoryMapper.insert(whsStorageInventory);
//                    } else {
//                        /** 防止多次提交，箱码数量都是 1，此处仅做更新操作 */
//                        whsStorageInventoryMapper.update(whsStorageInventory, queryWrapper);
//                    }
//                }
//            }
//            return ResponseResult.success();
//        }catch (Exception e){
//            System.out.println("======= insertSapDeliveryNote " + e);
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//            return ResponseResult.error();
//        }
//    }

    /**
     * {
     * "deliveryNoteSap": "1180066360",
     * "plaEndDate": "20210414",
     * "plaStartDate": "20210301",
     * "spmsStatus":"3",
     * "pageNo": "1",
     * "pageSize": "20"
     * }
     *
     * @param doc
     * @return
     */
    @Override
    public Map<String, Object> getSpDeliveryNoteTask(String userId, JSONObject doc) {
        String deliveryNoteSap = StringUtils.isNotEmpty(doc.getString("deliveryNoteSap")) ? doc.getString("deliveryNoteSap") : null;
        String plaStartDate = StringUtils.isNotEmpty(doc.getString("plaStartDate")) ? doc.getString("plaStartDate") : null;
        String plaEndDate = StringUtils.isNotEmpty(doc.getString("plaEndDate")) ? doc.getString("plaEndDate") : null;
        String spmsStatus = StringUtils.isNotEmpty(doc.getString("spmsStatus")) ? doc.getString("spmsStatus") : null;
        int pageNo = StringUtils.isNotEmpty(doc.getString("pageNo")) ? doc.getInteger("pageNo") : 1;
        int pageSize = StringUtils.isNotEmpty(doc.getString("pageSize")) ? doc.getInteger("pageSize") : 20;
        PageHelper.startPage(pageNo, pageSize);
        List<Map<String, Object>> sapDeliveryNote = this.baseMapper.getSpDeliveryNoteTask(userId, deliveryNoteSap, plaStartDate, plaEndDate, spmsStatus);
        DataToPage dataToPage = new DataToPage();
        return dataToPage.toPageData(sapDeliveryNote);
    }


    /** 单据状态控制：0-待到货；1-已到货；2-下发到PDA；3-收货中；4-待上架；5-上架中；6-已验收待上传SAP；7-提交SAP失败；8-提交SAP完成；9-回撤重新入库；10-部分完成；11-关闭；
     * 关闭/开启自管仓交货单，关闭单据 operateType = 0，开启单据 operateType = 1；
     * 关闭单据状态变化：null 或 0 —— 11；  开启单据状态变化：11 —— 0；
     * */
    @Override
    public synchronized ResponseResult closeOrOpenSapDeliveryNote(String deliveryNoteSap, String operateType, String userId) {
        if (StringUtils.isEmpty(deliveryNoteSap) || StringUtils.isEmpty(operateType)){
            return ResponseResult.error("请求参数错误");
        }
        if (!"0".equals(operateType) && !"1".equals(operateType)){
            return ResponseResult.error("请求参数错误");
        }
        QueryWrapper<SapDeliveryNote> queryWrapper = new QueryWrapper<SapDeliveryNote>().eq("DELIVERY_NOTE_SAP", deliveryNoteSap);
        SapDeliveryNote sapDeliveryNote = this.baseMapper.selectOne(queryWrapper);
        if (sapDeliveryNote == null){
            return ResponseResult.error("查询该交货单不存在");
        }
        String spmsStatus = sapDeliveryNote.getSpmsStatus();
        if ("0".equals(operateType)){
            if (StringUtils.isEmpty(spmsStatus) || "0".equals(spmsStatus)){
                sapDeliveryNote.setSpmsStatus("11");
                this.baseMapper.update(sapDeliveryNote, queryWrapper);
                iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(deliveryNoteSap, userId, UPDATE_SAP_DELIVERY_NOTE11);
                return ResponseResult.success().add("sapDeliveryNote", this.baseMapper.selectOne(queryWrapper));
            } else {
                return ResponseResult.error("交货单当前状态禁止关闭操作");
            }
        } else {
            if (StringUtils.isEmpty(spmsStatus)){
                return ResponseResult.error("交货单当前状态禁止开启操作");
            }
            if (!"11".equals(spmsStatus)){
                return ResponseResult.error("交货单当前状态禁止开启操作");
            }
            sapDeliveryNote.setSpmsStatus("0");
            this.baseMapper.update(sapDeliveryNote, queryWrapper);
            iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(deliveryNoteSap, userId, "已开启");
            return ResponseResult.success().add("sapDeliveryNote", this.baseMapper.selectOne(queryWrapper));
        }
    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    /** 获取来自 SAP 系统的送货单交货单任务——自管仓入库任务等信息并更新相关数据 */
    public void insertSapDeliveryNote(JSONObject doc) {
        try {
            /** 交货单表头 */
            JSONArray IT_LIKP = doc.getJSONArray("IT_LIKP");
            /** 交货单行项目 */
            JSONArray IT_LIPS = doc.getJSONArray("IT_LIPS");
            /** 交货单表头供应商信息 */
            JSONArray IT_LIFNR = doc.getJSONArray("IT_LIFNR");

            /** 包装单号表 */
            JSONArray IT_HEAD = doc.getJSONArray("IT_HEAD");
            /** 箱码表表头 */
            JSONArray IT_XHEAD = doc.getJSONArray("IT_XHEAD");
            /** 箱码行项目 */
            JSONArray IT_ITME = doc.getJSONArray("IT_ITME");

            insertDNTitle(IT_LIKP);
            insertDNDtl(IT_LIPS);
            insertDNSupplier(IT_LIFNR);

            insertSapPackageNote(IT_HEAD);
            insertSapBoxNote(IT_XHEAD);
            insertSapBoxNoteDtl(IT_ITME);

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("======= insertSapDeliveryNote " + e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

    void insertDNTitle(JSONArray IT_LIKP) {
        for (int i = 0; i < IT_LIKP.size(); i++) {
            //System.out.println("=======" + IT_LIKP.size() + "    " + i + "   SAP 交货单表头信息  " + IT_LIKP.get(i).toString());
            JSONObject json = JSONObject.parseObject(IT_LIKP.get(i).toString());
            if (StringUtils.isNotEmpty(json.toString())) {
                SapDeliveryNote deliveryNote = new SapDeliveryNote();
                deliveryNote.setDeliveryNoteSap(json.getString("VBELN"));
                deliveryNote.setPlannedArrivalDate(json.getString("LFDAT"));
                deliveryNote.setDeliveryNoteSrm(json.getString("LIFEX"));
                deliveryNote.setDeliveryType(json.getString("LFART"));
                deliveryNote.setSpmsMark(json.getString("ZSPMS"));
                deliveryNote.setCreateDateSap(json.getString("ERDAT"));
                deliveryNote.setSupplierCode(json.getString("LIFNR"));
                deliveryNote.setPackageNote(json.getString("PACKAGE_NO"));
                if (this.baseMapper.selectOne(new QueryWrapper<SapDeliveryNote>()
                        .eq("DELIVERY_NOTE_SAP", deliveryNote.getDeliveryNoteSap())) != null) {
                    this.baseMapper.update(deliveryNote, new QueryWrapper<SapDeliveryNote>()
                            .eq("DELIVERY_NOTE_SAP", deliveryNote.getDeliveryNoteSap()));
                } else {
                    this.baseMapper.insert(deliveryNote);
                }

            }
        }
    }

    void insertDNDtl(JSONArray IT_LIPS) {
        for (int i = 0; i < IT_LIPS.size(); i++) {
            //System.out.println("=======" + IT_LIPS.size() + "    " + i + "   SAP 交货单行项目信息  " + IT_LIPS.get(i).toString());
            JSONObject json = JSONObject.parseObject(IT_LIPS.get(i).toString());
            if (StringUtils.isNotEmpty(json.toString())) {
                SapDeliveryNoteDtl deliveryNoteDtl = new SapDeliveryNoteDtl();
                deliveryNoteDtl.setDeliveryNoteSap(json.getString("VBELN"));
                deliveryNoteDtl.setDeliveryNoteSapItem(Integer.parseInt(json.getString("POSNR")));
                deliveryNoteDtl.setPurchaseGroup(json.getString("ZEKGRP"));
                deliveryNoteDtl.setPurchaseGroupName(json.getString("ZEKNAM"));
                deliveryNoteDtl.setMaterialNo(json.getString("MATNR"));
                //deliveryNoteDtl.setDeliveryQty(Double.parseDouble(json.getString("LFIMG")));
                /** 用字段LGMNG（基本单位数量）替换LFIMG（销售单位数量） ———— 20210817 */
                deliveryNoteDtl.setDeliveryQty(Double.parseDouble(json.getString("LGMNG")));
                //deliveryNoteDtl.setDeliveryUnit(json.getString("VRKME"));
                /** 用字段MEINS基本单位替换VRKME；DeliveryUnit固定存基本单位； */
                deliveryNoteDtl.setDeliveryUnit(json.getString("MEINS"));
                deliveryNoteDtl.setWerks(json.getString("WERKS"));
                deliveryNoteDtl.setWhsLocationCode(json.getString("LGORT"));
                deliveryNoteDtl.setOverDeliveryLimit(StringUtils.isNotEmpty(json.getString("UEBTO")) ? Double.parseDouble(json.getString("UEBTO")) : 0);
                deliveryNoteDtl.setUnderDeliveryLimit(StringUtils.isNotEmpty(json.getString("UNTTO")) ? Double.parseDouble(json.getString("UNTTO")) : 0);
                deliveryNoteDtl.setUnlimited(json.getString("UEBTK"));
                deliveryNoteDtl.setItemStatus(String.valueOf(0));
                deliveryNoteDtl.setWerksXq(json.getString("WERKS_XQ"));
                deliveryNoteDtl.setQtySales(StringUtils.isEmpty(json.getString("QTY_SALES")) ? 0.0 : json.getDoubleValue("QTY_SALES"));
                deliveryNoteDtl.setUnitSales(json.getString("UNIT_SALES"));
                QueryWrapper<SapDeliveryNoteDtl> queryWrapper = new QueryWrapper<SapDeliveryNoteDtl>()
                        .eq("DELIVERY_NOTE_SAP", deliveryNoteDtl.getDeliveryNoteSap())
                        .eq("DELIVERY_NOTE_SAP_ITEM", deliveryNoteDtl.getDeliveryNoteSapItem());
                if (sapDeliveryNoteDtlMapper.selectOne(queryWrapper) != null) {
                    sapDeliveryNoteDtlMapper.update(deliveryNoteDtl, queryWrapper);
                } else {
                    sapDeliveryNoteDtlMapper.insert(deliveryNoteDtl);
                }
            }
        }
    }

    void insertDNSupplier(JSONArray IT_LIFNR) {
        for (int i = 0; i < IT_LIFNR.size(); i++) {
            //System.out.println("=======" + IT_LIFNR.size() + "    " + i + "   SAP 交货单表头供应商信息  " + IT_LIFNR.get(i).toString());
            JSONObject json = JSONObject.parseObject(IT_LIFNR.get(i).toString());
            if (StringUtils.isNotEmpty(json.toString())) {
                SapDeliveryNote deliveryNote = new SapDeliveryNote();
                deliveryNote.setDeliveryNoteSap(json.getString("VBELN"));
                deliveryNote.setSupplierCode(json.getString("LIFNR"));
                deliveryNote.setSupplierDesc(json.getString("ZTEXT"));
                QueryWrapper<SapDeliveryNote> queryWrapper = new QueryWrapper<SapDeliveryNote>()
                        .eq("DELIVERY_NOTE_SAP", deliveryNote.getDeliveryNoteSap());
                if (this.baseMapper.selectOne(queryWrapper) != null) {
                    this.baseMapper.update(deliveryNote, queryWrapper);
                } else {
                    this.baseMapper.insert(deliveryNote);
                }

            }
        }
    }

    void insertSapPackageNote(JSONArray IT_HEAD) {
        if (IT_HEAD.size() > 0) {
            for (int i = 0; i < IT_HEAD.size(); i++) {
                System.out.println("=======" + IT_HEAD.size() + "    " + i + "   SAP 包装单表  " + IT_HEAD.get(i).toString());
                JSONObject json = IT_HEAD.getJSONObject(i);
                if (StringUtils.isNotEmpty(json.toString())) {
                    SapPackageNote packageNote = new SapPackageNote();
                    packageNote.setPackageNote(json.getString("PACKAGE_NO"));
                    packageNote.setDeliveryNoteSrm(json.getString("SRM_DN"));
                    packageNote.setDeliveryNoteSap(json.getString("SAP_DN"));
                    packageNote.setSupplierCode(json.getString("LIFNR"));
                    packageNote.setTotalVolume(StringUtils.isEmpty(json.getString("VOLUM_T")) ? 0.000 : Double.parseDouble(json.getString("VOLUM_T")));
                    packageNote.setTotalWeight(StringUtils.isEmpty(json.getString("BRGEW_T")) ? 0.000 : Double.parseDouble(json.getString("BRGEW_T")));
                    packageNote.setLoadBeginTime(json.getString("ZXDATE_F"));
                    packageNote.setLoadEndTime(json.getString("ZXDATE_T"));
                    packageNote.setTransporter(json.getString("YSR"));
                    packageNote.setContractorInfo(json.getString("CYRLXFS"));
                    packageNote.setReceiver(json.getString("SHR"));
                    packageNote.setReceiverInfo(json.getString("SHRLXFS"));
                    packageNote.setReceivingAddress(json.getString("SHDZ"));
                    packageNote.setSpmsContractNote(json.getString("SPMS_CONTRACT_NO"));
                    packageNote.setSpmsMark(json.getString("SPMS_FLG"));
                    QueryWrapper<SapPackageNote> queryWrapper = new QueryWrapper<SapPackageNote>().eq("PACKAGE_NOTE", json.getString("PACKAGE_NO"));
                    if (sapPackageNoteMapper.selectOne(queryWrapper) != null) {
                        sapPackageNoteMapper.update(packageNote, queryWrapper);
                    } else {
                        sapPackageNoteMapper.insert(packageNote);
                    }
                }
            }
        }
    }

    void insertSapBoxNote(JSONArray IT_XHEAD) {
        if (IT_XHEAD.size() > 0) {
            for (int i = 0; i < IT_XHEAD.size(); i++) {
                System.out.println("=======" + IT_XHEAD.size() + "    " + i + "   SAP 箱码表  " + IT_XHEAD.get(i).toString());
                JSONObject json = IT_XHEAD.getJSONObject(i);
                if (StringUtils.isNotEmpty(json.toString())) {
                    SapBoxNote sapBoxNote = new SapBoxNote();
                    sapBoxNote.setPackageNote(json.getString("PACKAGE_NO"));
                    sapBoxNote.setBoxNote(json.getString("PACKAGE_CODE"));
                    sapBoxNote.setBoxMaterialName(json.getString("OUTER_BOX_TEXTURE"));
                    sapBoxNote.setTotalQty(StringUtils.isEmpty(json.getString("TOTAL_QTY")) ? 0 : Double.valueOf(json.getString("TOTAL_QTY")).intValue());
                    sapBoxNote.setBoxGrossWeight(StringUtils.isEmpty(json.getString("BOX_BRGEW")) ? 0.000 : Double.parseDouble(json.getString("BOX_BRGEW")));
                    sapBoxNote.setBoxVolume(StringUtils.isEmpty(json.getString("BOX_VOLUM")) ? 0.000 : Double.parseDouble(json.getString("BOX_VOLUM")));
                    sapBoxNote.setBoxLength(StringUtils.isEmpty(json.getString("LENGTH")) ? 0.000 : Double.parseDouble(json.getString("LENGTH")));
                    sapBoxNote.setBoxWidth(StringUtils.isEmpty(json.getString("WIDTH")) ? 0.000 : Double.parseDouble(json.getString("WIDTH")));
                    sapBoxNote.setBoxHeight(StringUtils.isEmpty(json.getString("HEIGHT")) ? 0.000 : Double.parseDouble(json.getString("HEIGHT")));
                    sapBoxNote.setBoxColor(json.getString("COLOR"));
                    sapBoxNote.setItemStatus(String.valueOf(0));
                    QueryWrapper<SapBoxNote> queryWrapper = new QueryWrapper<SapBoxNote>().eq("BOX_NOTE", json.getString("PACKAGE_CODE"));
                    if (sapBoxNoteMapper.selectOne(queryWrapper) != null) {
                        sapBoxNoteMapper.update(sapBoxNote, queryWrapper);
                    } else {
                        sapBoxNoteMapper.insert(sapBoxNote);
                    }
                }
            }
        }
    }

    void insertSapBoxNoteDtl(JSONArray IT_ITME) {
        if (IT_ITME.size() > 0) {
            for (int i = 0; i < IT_ITME.size(); i++) {
                System.out.println("=======" + IT_ITME.size() + "    " + i + "   SAP 箱码明细表  " + IT_ITME.get(i).toString());
                JSONObject json = IT_ITME.getJSONObject(i);
                if (StringUtils.isNotEmpty(json.toString())) {
                    SapBoxNoteDtl sapBoxNoteDtl = new SapBoxNoteDtl();
                    sapBoxNoteDtl.setPackageNote(json.getString("PACKAGE_NO"));
                    sapBoxNoteDtl.setItem(StringUtils.isEmpty(json.getString("SERIAL")) ? null : Integer.parseInt(json.getString("SERIAL")));
                    sapBoxNoteDtl.setBoxNote(json.getString("PACKAGE_CODE"));
                    sapBoxNoteDtl.setPackagePosnr(StringUtils.isEmpty(json.getString("PACKAGE_POSNR")) ? null : Integer.parseInt(json.getString("PACKAGE_POSNR")));
                    sapBoxNoteDtl.setMaterialNo(json.getString("MATNR"));
                    sapBoxNoteDtl.setSpecs(json.getString("SPECS"));
                    sapBoxNoteDtl.setQuantity(StringUtils.isEmpty(json.getString("MENGE")) ? 0.000 : Double.parseDouble(json.getString("MENGE")));
                    sapBoxNoteDtl.setBasicUnit(json.getString("MEINS"));
                    sapBoxNoteDtl.setSrmContractNo(json.getString("SRM_CONTRACT_NO"));
                    sapBoxNoteDtl.setPurchaseNo(json.getString("EBELN"));
                    sapBoxNoteDtl.setPurchaseNoItem(StringUtils.isEmpty(json.getString("EBELP")) ? null : Integer.parseInt(json.getString("EBELP")));
                    sapBoxNoteDtl.setDeliveryNoteSap(json.getString("VBELN"));
                    sapBoxNoteDtl.setDeliveryNoteSapItem(StringUtils.isEmpty(json.getString("POSNR")) ? null : Integer.parseInt(json.getString("POSNR")));
                    sapBoxNoteDtl.setDemandNo(json.getString("DEMAND_NO"));
                    sapBoxNoteDtl.setDemandNoItem(StringUtils.isEmpty(json.getString("DEMAND_POSNR")) ? null : Integer.parseInt(json.getString("DEMAND_POSNR")));
                    sapBoxNoteDtl.setDemander(json.getString("DEMANDER"));
                    sapBoxNoteDtl.setRemark(json.getString("MARK"));
                    sapBoxNoteDtl.setGrossWeight(StringUtils.isEmpty(json.getString("BRGEW")) ? 0.000 : Double.parseDouble(json.getString("BRGEW")));
                    sapBoxNoteDtl.setNetWeight(StringUtils.isEmpty(json.getString("NTGEW")) ? 0.000 : Double.parseDouble(json.getString("NTGEW")));
                    sapBoxNoteDtl.setDomesticQtyReceivable(StringUtils.isEmpty(json.getString("GNSHSL")) ? null : Double.parseDouble(json.getString("GNSHSL")));
                    //sapBoxNoteDtl.setDomesticQtyReceived(StringUtils.isEmpty(json.getString("GNSJSL")) ? null : Double.parseDouble(json.getString("GNSJSL")));
                    //sapBoxNoteDtl.setOverseaQtyReceived(StringUtils.isEmpty(json.getString("HWSHSL")) ? null : Double.parseDouble(json.getString("HWSHSL")));
                    QueryWrapper<SapBoxNoteDtl> queryWrapper = new QueryWrapper<SapBoxNoteDtl>()
                            .eq("BOX_NOTE", json.getString("PACKAGE_CODE"))
                            .eq("ITEM", json.getString("SERIAL"));
                    if (sapBoxNoteDtlMapper.selectOne(queryWrapper) != null) {
                        sapBoxNoteDtlMapper.update(sapBoxNoteDtl, queryWrapper);
                    } else {
                        sapBoxNoteDtlMapper.insert(sapBoxNoteDtl);
                    }
                }
            }
        }
    }

    /***
     * 根据交货单号获取交货单表头及明细信息，提交给SAP
     * @param deliveryNoteSap
     * @return
     */
    @Override
    public synchronized Map<String, Object> getDnDataToSap(String deliveryNoteSap, String postingDate, String userId, String remarks, String operateUser) {
        if (StringUtils.isEmpty(deliveryNoteSap)) {
            return null;
        }
        try {
            Map<String, Object> map = new HashMap<>();
            SapDeliveryNote sapDeliveryNote = this.baseMapper.selectOne(new QueryWrapper<SapDeliveryNote>().eq("DELIVERY_NOTE_SAP", deliveryNoteSap));
            /** 提交前交货单状态需为 6 - 已验收待上传SAP 或 7 - 提交SAP失败；不为 6 或 7 的返回空。 提交SAP前将 过账日期 - postingDate 字段写入该条数据 */
            if (sapDeliveryNote != null && ("6".equals(sapDeliveryNote.getSpmsStatus()) || "7".equals(sapDeliveryNote.getSpmsStatus()))) {
                /** 将 postingDate 字段写入该条数据 */
                sapDeliveryNote.setPostingDate(postingDate);
                if (StringUtils.isNotEmpty(remarks)){
                    sapDeliveryNote.setRemarks(remarks);
                }
                if (StringUtils.isNotEmpty(operateUser)){
                    sapDeliveryNote.setOperateUser(operateUser);
                }
                int resp = this.baseMapper.update(sapDeliveryNote, new QueryWrapper<SapDeliveryNote>().eq("DELIVERY_NOTE_SAP", deliveryNoteSap));
                if (resp <= 0) {
                    return null;
                }
                /** 提交SAP 和 重新提交SAP 记录日志信息 */
                insertSapDnLog(deliveryNoteSap, sapDeliveryNote.getSpmsStatus(), userId);

                Map<String, Object> Head = new HashMap<>();
                List<Map<String, Object>> Items = new ArrayList<>();
                /** sapDeliveryNoteDtlList 用于存储 贸易货 交货单行项目数据 */
                List<Map<String, Object>> sapDeliveryNoteDtlList = new ArrayList<>();
                /** sapBoxNoteDtlList 用于存储 备件货 由箱码明细数据转换成的交货行项目数据 */
                List<Map<String, Object>> sapBoxNoteDtlList = new ArrayList<>();
                /**
                 Head.put("xblnr", StringUtils.isNotEmpty(sapDeliveryNote.getDeliveryNoteSrm()) ? sapDeliveryNote.getDeliveryNoteSrm() : "");
                 Z_SPMS_MIGO 回写SAP传值 xblnr 也传值 DELIVERY_NOTE_SAP ———— 20210906 wayne
                 */
                Head.put("xblnr", StringUtils.isNotEmpty(sapDeliveryNote.getDeliveryNoteSap()) ? sapDeliveryNote.getDeliveryNoteSap() : "");
                Head.put("vbelnIm", StringUtils.isNotEmpty(sapDeliveryNote.getDeliveryNoteSap()) ? sapDeliveryNote.getDeliveryNoteSap() : "");
                Head.put("bldat", StringUtils.isNotEmpty(sapDeliveryNote.getDocumentDate()) ? sapDeliveryNote.getDocumentDate() : "");
                //Head.put("budat", StringUtils.isNotEmpty(sapDeliveryNote.getPostingDate()) ? sapDeliveryNote.getPostingDate() : "");
                Head.put("budat", postingDate);
                Head.put("createdby", StringUtils.isNotEmpty(sapDeliveryNote.getUserId()) ? sapDeliveryNote.getUserId() : "");
                //移动类型采购入库 101；免费入库511；
                Head.put("bwart", StringUtils.isNotEmpty(sapDeliveryNote.getMobileType()) ? sapDeliveryNote.getMobileType() : "101");
                Head.put("bktxt", StringUtils.isNotEmpty(sapDeliveryNote.getRemarks()) ? sapDeliveryNote.getRemarks() : " ");

                /** sapDeliveryNote.getPackageNote() 为空贸易货；不为空备件货；*/
                if (StringUtils.isEmpty(sapDeliveryNote.getPackageNote())) {
                    /** 实际收货数量字段值为空的不会被提交，查询条件还需完善 */
                    /**
                     sapDeliveryNoteDtlList = sapDeliveryNoteDtlMapper.selectList(new QueryWrapper<SapDeliveryNoteDtl>()
                     .eq("DELIVERY_NOTE_SAP", deliveryNoteSap).gt("RECEIVED_QTY", 0));
                     ———— 20210908 取值修改，基本单位不取 SAP_DELIVERY_NOTE_DTL.DELIVERY_UNIT 改取物料的基本单位；
                     */
                    sapDeliveryNoteDtlList = sapDeliveryNoteDtlMapper.getDeliveryNoteDtlToSap(deliveryNoteSap);
                    if (sapDeliveryNoteDtlList.size() == 0) {
                        return null;
                    }
                    for (Map<String, Object> sapDeliveryNoteDtl : sapDeliveryNoteDtlList) {
                        Map<String, Object> Item = new HashMap<>();
                        Item.put("vbelnIm", sapDeliveryNoteDtl.get("deliveryNoteSap").toString());
                        Item.put("vbelpIm", String.valueOf(sapDeliveryNoteDtl.get("deliveryNoteSapItem")));
                        Item.put("matnr", sapDeliveryNoteDtl.get("materialNo").toString());
                        Item.put("bstmg", sapDeliveryNoteDtl.get("receivedQty").toString());
                        Item.put("bstme", sapDeliveryNoteDtl.get("basicUnit").toString());
                        Item.put("werks", sapDeliveryNoteDtl.get("werks").toString());
                        Item.put("lgort", sapDeliveryNoteDtl.get("whsLocationCode").toString());
                        Item.put("sgtxt", sapDeliveryNoteDtl.get("remarks") == null ? " " : sapDeliveryNoteDtl.get("remarks").toString());
                        Items.add(Item);
                    }
                } else {
                    sapBoxNoteDtlList = this.baseMapper.getBoxNoteDtlToSap(deliveryNoteSap);
                    if (sapBoxNoteDtlList.size() == 0) {
                        return null;
                    }
                    for (Map<String, Object> sapBoxNoteMaterial : sapBoxNoteDtlList) {
                        Map<String, Object> Item = new HashMap<>();
                        Item.put("vbelnIm", sapBoxNoteMaterial.get("deliveryNoteSap").toString());
                        Item.put("vbelpIm", sapBoxNoteMaterial.get("deliveryNoteSapItem").toString());
                        Item.put("matnr", sapBoxNoteMaterial.get("materialNo").toString());
                        Item.put("bstmg", sapBoxNoteMaterial.get("domesticQtyReceived").toString());
                        Item.put("bstme", sapBoxNoteMaterial.get("basicUnit").toString());
                        Item.put("werks", sapBoxNoteMaterial.get("werks").toString());
                        Item.put("lgort", sapBoxNoteMaterial.get("whsLocationCode").toString());
                        /** sgtxt - 项目文本。备件按箱存储，交货单一行可能跨越多个箱子，无法留存备注信息。 */
                        Item.put("sgtxt", " ");
                        Items.add(Item);
                    }
                }
                map.put("Head", Head);
                map.put("Items", Items);
                return Z_SPMS_MIGO(map);
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据交货单提交前状态判断交货但是 提交SAP 还是 重提SAP，然后记录单据操作日志。
     */
    void insertSapDnLog(String deliveryNoteSap, String spmsStatus, String userId) {
        if ("6".equals(spmsStatus)) {
            iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(deliveryNoteSap, userId, SUBMIT_SAP_DELIVERY_NOTE_SAP);
        }
        if ("7".equals(spmsStatus)) {
            iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(deliveryNoteSap, userId, RESUBMIT_SAP_DELIVERY_NOTE_SAP);
        }
    }

    public Map<String, Object> Z_SPMS_MIGO(Map<String, Object> map) {
        String mqUuid = UUID.randomUUID().toString();
        JSONObject doc = new JSONObject();
        JSONObject REQUEST = new JSONObject();
        JSONObject ESB_ATTRS = new JSONObject();
        JSONObject REQUEST_DATA = new JSONObject();

        ESB_ATTRS.put("Application_ID", "00020000000002");
        ESB_ATTRS.put("Transaction_ID", mqUuid);
        ESB_ATTRS.put("App_ID", "SPMS");

        REQUEST_DATA.put("Operation", "Z_SPMS_MIGO");
        REQUEST_DATA.put("Type", "SPMS_MIGO");
        REQUEST_DATA.put("Head", map.get("Head"));
        REQUEST_DATA.put("Items", map.get("Items"));

        REQUEST.put("ESB_ATTRS", ESB_ATTRS);
        REQUEST.put("REQUEST_DATA", REQUEST_DATA);

        doc.put("REQUEST", REQUEST);
        return doc;
    }

    /**
     * 来货验收结果更新接口，备件货箱数验收结果更新。
     * 1.更新交货单表头状态；
     * 2.更新箱码表实收箱数量；
     * 3.更新箱码明细表物料实收数量；
     * 4.生成上架任务；
     * 5.生成上架任务明细；
     * {
     * "pdaSn": "pda20210412",
     * "documentDate": "20200412",
     * "sapDeliveryNote": {
     * "deliveryNoteSap": "1180066380",
     * "mobileType":"101",
     * "spmsStatus": "6"
     * },
     * "sapBoxNote": [{
     * "boxNote": "ZX-10215800021-0202",
     * "boxQtyReceived": 1,
     * "remarks": "说明信息"
     * }]
     * }
     *
     * @param doc
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult checkSapDeliveryNote(String userId, JSONObject doc) {
        try {
            if (!doc.containsKey("sapDeliveryNote") || !doc.containsKey("sapBoxNote") || doc.getJSONArray("sapBoxNote").size() == 0) {
                return ResponseResult.error("请求参数错误");
            }
            String pdaSn=doc.getString("pdaSn");
            String documentDate = doc.getString("documentDate").replaceAll("-", "");

            /** 更新备件货交货单表头状态 */
            JSONObject sapDeliveryNote = doc.getJSONObject("sapDeliveryNote");
            String remarks=sapDeliveryNote.getString("remarks");
            String operateUser=sapDeliveryNote.getString("operateUser");
            int resp = updateSapDeliveryNoteHead(sapDeliveryNote, documentDate, userId,pdaSn,remarks, operateUser);

            if (resp == -1) {

                return ResponseResult.error("单据状态已验收请勿重复提交", 409);
            }
            /** 表头更新成功后，更新备件货交货单箱码实收数量等信息 */
            if (resp > 0) {
                /** 给交货单表头增加操作日志 —— 已验收待上传SAP */
                iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(sapDeliveryNote.getString("deliveryNoteSap"), userId, UPDATE_SAP_DELIVERY_NOTE6);

                JSONArray sapBoxNote = doc.getJSONArray("sapBoxNote");
                updateSapBoxNoteHead(sapBoxNote, documentDate);

                /** 箱码实收数量为1，则后台自动更新箱码明细的物料 国内收货数量 等于 应收数量 */
                updateSapBoxNoteDtl(sapBoxNote);

                /** 将箱码入库到仓库库存，由于箱码永远唯一所以仓库库存表，对每个箱码直接增加一条数据即可。 */
                addBoxNoteToWhsInventoryInfo(sapDeliveryNote, sapBoxNote, userId);
            }
            /** 新建上架任务表头及明细 */
            int result = iShelfOnTaskService.generateShelfOnTask(userId, documentDate, sapDeliveryNote.getString("deliveryNoteSap"), "1",pdaSn);

            return ResponseResult.success();

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("======= checkSapDeliveryNote " + e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseResult.error();
        }
    }

    /**
     * 更新备件货交货单表头状态
     */
    int updateSapDeliveryNoteHead(JSONObject json, String documentDate, String userId,String pdaSn,String remarks, String operateUser) {
        SapDeliveryNote sapDeliveryNote = new SapDeliveryNote();
        sapDeliveryNote.setDeliveryNoteSap(json.getString("deliveryNoteSap"));
        sapDeliveryNote.setSpmsStatus(json.getString("spmsStatus"));
        sapDeliveryNote.setMobileType(json.getString("mobileType"));
        sapDeliveryNote.setUserId(userId);
        sapDeliveryNote.setDocumentDate(documentDate);
        sapDeliveryNote.setPdaSN(pdaSn);
        sapDeliveryNote.setRemarks(remarks);
        if (StringUtils.isNotEmpty(operateUser)){
            sapDeliveryNote.setOperateUser(operateUser);
        }
        QueryWrapper<SapDeliveryNote> queryWrapper = new QueryWrapper<SapDeliveryNote>().eq("DELIVERY_NOTE_SAP", json.getString("deliveryNoteSap"));
        SapDeliveryNote deliveryNote = this.baseMapper.selectOne(queryWrapper);
        if ("6".equals(deliveryNote.getSpmsStatus())) {
            return -1;
        }
        return this.baseMapper.update(sapDeliveryNote, queryWrapper);
    }

    /**
     * 更新备件货交货单箱码实收数量等信息
     */
    void updateSapBoxNoteHead(JSONArray array, String documentDate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("YYYYMMdd");
        SimpleDateFormat sdf1 = new SimpleDateFormat("YYYY-MM-dd");
        System.out.println(array.toJSONString());
        for (int i = 0; i < array.size(); i++) {
            SapBoxNote sapBoxNote = new SapBoxNote();
            sapBoxNote.setBoxNote(array.getJSONObject(i).getString("boxNote"));
            /** 实收数量为0或无实收数量的,实际实收为0 */
            if(StringUtils.isEmpty(array.getJSONObject(i).getString("boxQtyReceived"))){
                sapBoxNote.setBoxQtyReceived(0);
            }else{
                sapBoxNote.setBoxQtyReceived(Integer.parseInt(array.getJSONObject(i).getString("boxQtyReceived")));
            }
            sapBoxNote.setArrivalDate(sdf1.format(sdf.parse(documentDate)));
            // 行项目状态改为侍上传SAP - 6
            sapBoxNote.setItemStatus("6");
            // if (StringUtils.isNotEmpty(array.getJSONObject(i).getString("boxQtyReceived"))
            //         && Integer.parseInt(array.getJSONObject(i).getString("boxQtyReceived")) != 0) {
            //     sapBoxNote.setBoxQtyReceived(Integer.parseInt(array.getJSONObject(i).getString("boxQtyReceived")));
            //     sapBoxNote.setArrivalDate(sdf1.format(sdf.parse(documentDate)));
            //     // 行项目状态改为侍上传SAP - 6
            //     sapBoxNote.setItemStatus("6");
            // }
            sapBoxNote.setRemarks(array.getJSONObject(i).getString("remarks"));
            sapBoxNoteMapper.update(sapBoxNote, new QueryWrapper<SapBoxNote>().eq("BOX_NOTE", array.getJSONObject(i).getString("boxNote")));
        }
    }

    /**
     * 实收箱数为 1 时，将箱码明细表中 DOMESTIC_QTY_RECEIVABLE——国内收货时箱的数量更新为入参数量；
     * 将物料的实收数量 DOMESTIC_QTY_RECEIVED——国内实际数量-国内收货时默认箱内对应物料数量；更新为 该物料的应收数量。
     */
    void updateSapBoxNoteDtl(JSONArray array) {
        for (int i = 0; i < array.size(); i++) {
            String boxNote = array.getJSONObject(i).getString("boxNote");
            double boxNoteQty = Double.parseDouble(StringUtils.isNotEmpty(array.getJSONObject(i).getString("boxQtyReceived"))?array.getJSONObject(i).getString("boxQtyReceived"):"0");
            if (boxNoteQty > 0) {
                iSapBoxNoteDtlService.updateSapBoxNoteDtl(boxNote, boxNoteQty);
            }
        }
    }

    /**
     * 备件货验收成功时，箱码信息进入到仓库库存
     */
    void addBoxNoteToWhsInventoryInfo(JSONObject sapDeliveryNote, JSONArray sapBoxNote, String userId) {
        iWhsInventoryInfoService.addBoxNoteToWhsInventoryInfo(sapDeliveryNote, sapBoxNote, userId);
    }

    /**
     * 根据交货单号更新单据状态，先校验原有状态是否正确，再更新到新的状态. 提交SAP成功时把 SAP物料凭证，SAP凭证年份一并写入。
     */
    @Override
    public int updateSapDeliveryNoteStatus(String deliveryNoteSap, String targetStatus,
                                           String sapVoucherNumber, String sapVoucherYear) {
        SapDeliveryNote sapDeliveryNote = this.baseMapper.selectOne(new QueryWrapper<SapDeliveryNote>().eq("DELIVERY_NOTE_SAP", deliveryNoteSap));
        if (sapDeliveryNote != null) {
            sapDeliveryNote.setSpmsStatus(targetStatus);
            if (StringUtils.isNotEmpty(sapVoucherNumber)) {
                sapDeliveryNote.setSapVoucherNumber(sapVoucherNumber);
            }
            if (StringUtils.isNotEmpty(sapVoucherYear)) {
                sapDeliveryNote.setSapVoucherYear(sapVoucherYear);
            }
            return this.baseMapper.update(sapDeliveryNote, new QueryWrapper<SapDeliveryNote>().eq("DELIVERY_NOTE_SAP", deliveryNoteSap));
        }
        return 0;
    }

    @Override
    public SapDeliveryNote getSapDnByDn(String deliveryNoteSap) {
        return this.baseMapper.selectOne(new QueryWrapper<SapDeliveryNote>().eq("DELIVERY_NOTE_SAP", deliveryNoteSap));
    }

    @Override
    public ResponseResult updateSapDeliveryNoteTask(JSONObject doc, String userId) {
        try {
            if (doc == null){
                return ResponseResult.error();
            }
            String deliveryNoteSap = doc.getString("deliveryNoteSap");
            String currentStatus = doc.getString("currentStatus");
            String targetStatus = doc.getString("targetStatus");
            if (StringUtils.isEmpty(deliveryNoteSap) ||
                    StringUtils.isEmpty(currentStatus) || StringUtils.isEmpty(targetStatus)){
                return ResponseResult.error("请求参数错误");
            }
            QueryWrapper<SapDeliveryNote> queryWrapper = new QueryWrapper<SapDeliveryNote>().eq("DELIVERY_NOTE_SAP", deliveryNoteSap);
            SapDeliveryNote dn = this.baseMapper.selectOne(queryWrapper);
            if (dn == null || dn.getSpmsStatus() == null || "0".equals(dn.getSpmsStatus())){
                String json = "{\n" +
                        "    \"REQUEST\": {\n" +
                        "        \"ESB_ATTRS\": {\n" +
                        "            \"App_ID\": \"SPMS\", \n" +
                        "            \"Application_ID\": \"00020000000002\", \n" +
                        "            \"Transaction_ID\": " + "\"" + UUID.randomUUID() + "\"" +
                        "        }, \n" +
                        "        \"REQUEST_DATA\": {\n" +
                        "            \"Head\": {\n" +
                        "                \"iVbeln\": " + "\"" + deliveryNoteSap + "\",\n" +
                        "                \"iStatus\": \"\"" +
                        "            }, \n" +
                        "            \"Operation\": \"Z_SPMS_GETDN_REST\", \n" +
                        "            \"Type\": \"GETDN\"\n" +
                        "        }\n" +
                        "    }\n" +
                        "}";
                String message = iFeignServiceCommon.sendRestToSapCommon(JSONObject.parseObject(json));
                log.info("============updateSapDeliveryNoteTask:" + message);
                JSONObject jsonObject = JSONObject.parseObject(message).getJSONObject("RESPONSE").getJSONObject("RETURN_DATA");
                /** 更新交货单表头、供应商、行项目等信息 */
                if (jsonObject.containsKey("O_TYPE") && "S".equals(jsonObject.getString("O_TYPE"))){

                    /** 更新备件货交货单、箱码、箱码明细数据之前，删除已有的箱码、箱码明细数据；需判断是否存在仓库库存和储位库存； */
                    ResponseResult deleteResult = deleteDnRelateDoc(deliveryNoteSap);
                    if (deleteResult.getCode() != SUCCESS){
                        return deleteResult;
                    }

                    insertSapDeliveryNote(jsonObject);
                    iSapDeliveryNoteLogService.insertSapRequestRecord(deliveryNoteSap, userId, UPDATE_DELIVERY_NOTE,
                            JSONObject.parseObject(message).toJSONString(), JSONObject.parseObject(json).toJSONString());
                }else {
                    iSapDeliveryNoteLogService.insertSapRequestRecord(deliveryNoteSap, userId, UPDATE_DELIVERY_NOTE_ERROR,
                            JSONObject.parseObject(message).toJSONString(), JSONObject.parseObject(json).toJSONString());
                }
            }

            List<Map<String, Object>> sapDeliveryNoteList = this.baseMapper.getSpDeliveryNoteTask(userId, deliveryNoteSap, null, null, null);
            if (sapDeliveryNoteList == null || sapDeliveryNoteList.size() == 0){
                return ResponseResult.error("请求交货单为 贸易货 或 交货单不存在 或 当前人权限下可操作仓库无权限");
            }

            /** 检查该交货单存在、为备件收货、有明细行数据、有包装单号、有箱码、有箱码明细，如果信息不完善则返回错误信息 */
            ResponseResult checkResult = checkDnDataValidate(deliveryNoteSap);
            if (checkResult.getCode() != SUCCESS){
                return checkResult;
            }

            /** 只有有仓库权限且交货单状态为 空 或 0 才能被PDA更新 */
            if (sapDeliveryNoteList.get(0).get("spmsStatus") != null && !"0".equals(sapDeliveryNoteList.get(0).get("spmsStatus").toString())){
                return ResponseResult.error("交货单当前状态禁止此操作");
            }

            SapDeliveryNote sapDeliveryNote = new SapDeliveryNote();
            sapDeliveryNote.setSpmsStatus(targetStatus);
            this.baseMapper.update(sapDeliveryNote, queryWrapper);

            updateSapBoxNoteByDn(deliveryNoteSap);
            iSapDeliveryNoteLogService.insertSapDeliveryNoteLogM(deliveryNoteSap, userId, UPDATE_SAP_DELIVERY_NOTE2);
            return ResponseResult.success().add("sapDN", this.baseMapper.getSpDeliveryNoteTask(userId, deliveryNoteSap, null, null, targetStatus));
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error("请求错误");
        }
    }

    /** 检查该交货单是否有明细行数据、是否有箱码、是否有箱码明细，如果信息不完善则返回错误信息 */
    ResponseResult checkDnDataValidate(String deliveryNoteSap){
        QueryWrapper<SapDeliveryNote> queryWrapper = new QueryWrapper<SapDeliveryNote>().eq("DELIVERY_NOTE_SAP", deliveryNoteSap);
        SapDeliveryNote sapDeliveryNote = this.baseMapper.selectOne(queryWrapper);
        if (sapDeliveryNote == null){
            return ResponseResult.error("请求交货单数据不存在，操作终止");
        }
        String packageNote = sapDeliveryNote.getPackageNote();
        if (StringUtils.isEmpty(packageNote)){
            return ResponseResult.error("请求交货单数据为贸易货，请勿在PDA操作");
        }

        QueryWrapper<SapDeliveryNoteDtl> dtlQueryWrapper = new QueryWrapper<SapDeliveryNoteDtl>().eq("DELIVERY_NOTE_SAP", deliveryNoteSap);
        List<SapDeliveryNoteDtl> sapDeliveryNoteDtlList = sapDeliveryNoteDtlMapper.selectList(dtlQueryWrapper);
        if (sapDeliveryNoteDtlList == null || sapDeliveryNoteDtlList.size() == 0){
            return ResponseResult.error("请求交货单明细数据不存在，操作终止");
        }

        QueryWrapper<SapPackageNote> packageNoteQueryWrapper = new QueryWrapper<SapPackageNote>().eq("PACKAGE_NOTE", packageNote);
        List<SapPackageNote> sapPackageNoteList = sapPackageNoteMapper.selectList(packageNoteQueryWrapper);
        if (sapPackageNoteList == null || sapPackageNoteList.size() == 0){
            return ResponseResult.error("请求交货单关联包装单号表数据为空，操作终止");
        }

        QueryWrapper<SapBoxNote> sapBoxNoteQueryWrapper = new QueryWrapper<SapBoxNote>().eq("PACKAGE_NOTE", packageNote);
        List<SapBoxNote> sapBoxNoteList = sapBoxNoteMapper.selectList(sapBoxNoteQueryWrapper);
        if (sapBoxNoteList == null || sapBoxNoteList.size() == 0){
            return ResponseResult.error("请求交货单关联箱码信息表数据为空，操作终止");
        }

        for (SapBoxNote sapBoxNote : sapBoxNoteList){
            String boxNote = sapBoxNote.getBoxNote();
            if (StringUtils.isEmpty(boxNote)){
                return ResponseResult.error("箱码信息表数据错误：" + sapBoxNote.toString());
            }
            QueryWrapper<SapBoxNoteDtl> sapBoxNoteDtlQueryWrapper = new QueryWrapper<SapBoxNoteDtl>().eq("BOX_NOTE", boxNote);
            List<SapBoxNoteDtl> sapBoxNoteDtlList = sapBoxNoteDtlMapper.selectList(sapBoxNoteDtlQueryWrapper);
            if (sapBoxNoteDtlList == null || sapBoxNoteDtlList.size() == 0){
                return ResponseResult.error("请求交货单关联箱码明细表数据为空，操作终止");
            }
        }
        return ResponseResult.success();
    }


    /** 交货单确认到货，更新关联的箱码信息，实收箱数，到货日期字段 */
    void updateSapBoxNoteByDn(String deliveryNoteSap){
        this.baseMapper.updateBoxNoteByDeliveryNoteSap(deliveryNoteSap);
    }

    @Override
    public ResponseResult lockSapDeliveryNote(String deliveryNoteSap, String userId) {
        if (StringUtils.isEmpty(deliveryNoteSap)){
            return ResponseResult.error("请求参数错误");
        }
        JSONObject dataToSap = formatDataToSapDnLock(deliveryNoteSap);
        JSONObject sapReturnedData = JSONObject.parseObject(iFeignServiceCommon.sendRestToSapCommon(dataToSap));
        JSONObject RETURN_DATA = sapReturnedData.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA");
        if (StringUtils.isEmpty(RETURN_DATA.getString("O_TYPE")) || !"S".equals(RETURN_DATA.getString("O_TYPE"))){
            iSapDeliveryNoteLogService.insertSapRequestRecord(deliveryNoteSap, userId, DELIVERY_NOTE_LOCK,
                    sapReturnedData.toJSONString(), dataToSap.toJSONString());
            return ResponseResult.error().add("dataToSap", dataToSap).add("sapReturnedData", sapReturnedData);
        }
        iSapDeliveryNoteLogService.insertSapRequestRecord(deliveryNoteSap, userId, DELIVERY_NOTE_LOCK_ERROR,
                sapReturnedData.toJSONString(), dataToSap.toJSONString());
        return ResponseResult.success().add("dataToSap", dataToSap).add("sapReturnedData", sapReturnedData);
    }

    JSONObject formatDataToSapDnLock(String deliveryNoteSap){
        JSONObject doc = new JSONObject();

        JSONObject REQUEST = new JSONObject();
        JSONObject ESB_ATTRS = new JSONObject();
        JSONObject REQUEST_DATA = new JSONObject();
        JSONObject Head = new JSONObject();

        ESB_ATTRS.put("App_ID", "SPMS");
        ESB_ATTRS.put("Application_ID", "00020000000002");
        ESB_ATTRS.put("Transaction_ID", UUID.randomUUID().toString());

        Head.put("iVbeln", deliveryNoteSap);
        Head.put("iStatus", "0");

        REQUEST_DATA.put("Head", Head);
        REQUEST_DATA.put("Operation", "Z_SPMS_GETDN_REST");
        REQUEST_DATA.put("Type", "GETDN");

        REQUEST.put("ESB_ATTRS", ESB_ATTRS);
        REQUEST.put("REQUEST_DATA", REQUEST_DATA);

        doc.put("REQUEST", REQUEST);
        return doc;

    }

    @Override
    public ResponseResult deleteDnRelateDoc(String deliveryNoteSap) {
        if (StringUtils.isEmpty(deliveryNoteSap)){
            return ResponseResult.success();
        }
        /** 根据交货单号获取相关的 箱码 信息 */
        List<Map<String, Object>> boxNoteList = this.baseMapper.getBoxNoteList(deliveryNoteSap);
        if (boxNoteList != null && boxNoteList.size() > 0){
            for (Map<String, Object> map : boxNoteList){
                if (map.get("boxNote") != null && StringUtils.isNotEmpty(map.get("boxNote").toString())){
                    String boxNote = map.get("boxNote").toString();
                    List<Map<String, Object>> whsInventoryInfoList = this.baseMapper.getWhsInventoryInfo(boxNote);
                    if (whsInventoryInfoList != null && whsInventoryInfoList.size() > 0){
                        return ResponseResult.error("箱码 " + boxNote + " 已存在仓库库存，无法删除请重试");
                    }
                    List<Map<String, Object>> whsStorageInventoryList = this.baseMapper.getWhsStorageInventory(boxNote);
                    if (whsStorageInventoryList != null && whsStorageInventoryList.size() > 0){
                        return ResponseResult.error("箱码 " + boxNote + " 已存在储位库存，无法删除请重试");
                    }
                }
            }
        }
        /** 箱码既不存在仓库库存也不存在储位库存，则可以执行 箱码、箱码明细 的删除操作 */
        if (boxNoteList != null && boxNoteList.size() > 0){
            for (Map<String, Object> map : boxNoteList) {
                String boxNote = map.get("boxNote").toString();
                QueryWrapper<SapBoxNote> sapBoxNoteQueryWrapper = new QueryWrapper<SapBoxNote>().eq("BOX_NOTE", boxNote);
                sapBoxNoteMapper.delete(sapBoxNoteQueryWrapper);

                QueryWrapper<SapBoxNoteDtl> sapBoxNoteDtlQueryWrapper = new QueryWrapper<SapBoxNoteDtl>().eq("BOX_NOTE", boxNote);
                sapBoxNoteDtlMapper.delete(sapBoxNoteDtlQueryWrapper);
            }
        }
        return ResponseResult.success();
    }

    @Override
    public void updateCancelSapDeliveryNote(String deliveryNoteSap, String cancelPostingDate, String cancelSapVoucherNumber, String cancelRemark) {
        if (StringUtils.isEmpty(deliveryNoteSap)){
            return;
        }
        QueryWrapper<SapDeliveryNote> queryWrapper = new QueryWrapper<SapDeliveryNote>().eq("DELIVERY_NOTE_SAP", deliveryNoteSap);
        SapDeliveryNote sapDeliveryNote = this.baseMapper.selectOne(queryWrapper);
        sapDeliveryNote.setCancelPostingDate(cancelPostingDate);
        sapDeliveryNote.setCancelSapVoucherNumber(cancelSapVoucherNumber);
        sapDeliveryNote.setCancelRemark(cancelRemark);
        this.baseMapper.update(sapDeliveryNote, queryWrapper);
    }
}



